#pragma once

template<typename T>
class RadioButton : public UIElement
{
	Vertex3FCRHWT m_border[4];
	Vertex3FCRHWT m_knob[4];
	Texture* m_texture;
	ui32 m_state;
	bool m_pressed;
	ui32 m_enable;

	typedef void (T::*CheckChange)(RadioButton<T>*, bool);
	CheckChange OnCheckChanged;
	T* m_instance;

	CFont m_text;

	std::string m_szText;

public:
	RadioButton(ui32 x, ui32 y, T* instance) : m_text("Fonts\\FrizQT__.ttf", "Friz Quadrata TT", 7, 15)
	{
		m_szText = "";
		m_enable = 1;

		m_instance = instance;
		OnCheckChanged = 0;

		m_position.x = (float)x;
		m_position.y = (float)y;

		m_size.x = 12.0f;
		m_size.y = 12.0f;

		m_texture = CTextureHandler::GetInstance()->GetTexture("Interface\\Buttons\\UI-RadioButton.blp");

		m_border[0].x = m_knob[0].x = (float)x;
		m_border[0].y = m_knob[0].y = (float)y;

		m_border[1].x = m_knob[1].x = (float)x + 12.0f;
		m_border[1].y = m_knob[1].y = (float)y;

		m_border[2].x = m_knob[2].x = (float)x + 12.0f;
		m_border[2].y = m_knob[2].y = (float)y + 12.0f;

		m_border[3].x = m_knob[3].x = (float)x;
		m_border[3].y = m_knob[3].y = (float)y + 12.0f;

		m_border[0].u = 2.0f / 64.0f;
		m_border[0].v = 1.0f / 16.0f;

		m_border[1].u = 14.0f / 64.0f;
		m_border[1].v = 1.0f / 16.0f;

		m_border[2].u = 14.0f / 64.0f;
		m_border[2].v = 13.0f / 16.0f;

		m_border[3].u = 2.0f / 64.0f;
		m_border[3].v = 13.0f / 16.0f;

		m_knob[0].u = 18.0f / 64.0f;
		m_knob[0].v = 1.0f / 16.0f;

		m_knob[1].u = 30.0f / 64.0f;
		m_knob[1].v = 1.0f / 16.0f;

		m_knob[2].u = 30.0f / 64.0f;
		m_knob[2].v = 13.0f / 16.0f;

		m_knob[3].u = 18.0f / 64.0f;
		m_knob[3].v = 13.0f / 16.0f;

		for(ui32 i = 0; i < 4; ++i)
		{
			m_border[i].dwcolor = m_knob[i].dwcolor = 0xFFFFFFFF;
			m_border[i].rhw = m_knob[i].rhw = 1.0f;
			m_border[i].z = m_knob[i].z = 1.0f;
		}

		m_state = 0;
		m_pressed = false;
	}

	void Draw()
	{
		if(!m_enable)
			for(ui32 i = 0; i < 4; ++i)
				m_border[i].dwcolor = m_knob[i].dwcolor = 0xFF5F5F5F;
		else
			for(ui32 i = 0; i < 4; ++i)
				m_border[i].dwcolor = m_knob[i].dwcolor = 0xFFFFFFFF;

		sD3D->SetFVF(VERTEX3FCRHWT);
		sD3D->SetTexture(0, *m_texture);
		sD3D->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, m_border, sizeof(Vertex3FCRHWT));
		if(m_state)
			sD3D->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, m_knob, sizeof(Vertex3FCRHWT));
		if(m_szText != "")
		{
			if(m_enable)
				m_text.DrawTextA((ui32)m_position.x + 14, (ui32)m_position.y, m_text.GetTextLen(m_szText), 30, m_szText);
			else
				m_text.DrawTextA((ui32)m_position.x + 14, (ui32)m_position.y, m_text.GetTextLen(m_szText), 30, m_szText, 0xFF5F5F5F);
		}
	}

	void SetText(std::string szNew, i32 texEntry = -1)
	{
		m_szText = sLocale.GetLocale(texEntry, szNew);
		m_size.x = 14.0f + m_text.GetTextLen(m_szText, true);
	}

	void MouseActivity(bool left, Vertex2F pos, bool up)
	{
		if(!m_enable)
			return;
		if(up)
		{
			if(m_pressed)
			{
				m_state = m_state > 0 ? 0 : 1;
				if(m_instance && OnCheckChanged)
					(m_instance->*OnCheckChanged)(this, m_state > 0);
			}
			m_pressed = false;
			return;
		}
		if(pos.x >= m_position.x && pos.x <= m_position.x + m_size.x &&
			pos.y >= m_position.y && pos.y <= m_position.y + m_size.y)
		{
			m_pressed = true;
		}
	}

	void SetCallback(CheckChange pFunc)
	{
		OnCheckChanged = pFunc;
	}

	void ModPosition(i32 dx, i32 dy)
	{
		m_position.x += dx;
		m_position.y += dy;

		for(ui32 i = 0; i < 4; ++i)
		{
			m_knob[i].x += dx;
			m_knob[i].y += dy;
			m_border[i].x += dx;
			m_border[i].y += dy;
		}
	}

	void Enable() { m_enable = 1; }
	void Disable() { m_enable = 0; }

	void Check() { m_state = 1; }
	void Uncheck() { m_state = 0; }

	bool GetChecked() { return m_state != 0; }
};